package com.betty.cscams.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.betty.cscams.common.exception.CscaException;
import com.betty.cscams.constant.SysConstants;
import com.betty.cscams.dao.BusSubjectMapper;
import com.betty.cscams.dao.SysFileMapper;
import com.betty.cscams.dao.SysUserMapper;
import com.betty.cscams.entity.*;
import com.betty.cscams.service.*;
import com.betty.cscams.util.EasyPoiUtil;
import com.betty.cscams.util.FileUtil;
import com.betty.cscams.util.SecurityUtils;
import com.betty.cscams.util.UUIDUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.SystemUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SysFileServiceImpl implements SysFileService {


    @Autowired
    private BusSportsService busSportsService;
    @Autowired
    private SysFileMapper sysFileMapper;
    @Autowired
    private BusExpandService busExpandService;
    @Autowired
    private BusIntellectualService busIntellectualService;
    @Autowired
    private BusMoralService busMoralService;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private BusScoreService busScoreService;
    @Autowired
    private BusSubjectMapper busSubjectMapper;

    @Value("${httpImgUrl}")
    private String httpImgUrl;

    /**
     * 导入成绩
     * @param file
     * @param termId
     * @param type  4 体育
     */
    @Override
    public void importExecl(MultipartFile file, Long termId, int type) throws Exception {
        if(type == 4){
            importExeclSports(file,termId,type);
        }else if(type == 3){
            importExeclExpand(file,termId,type);
        }else if(type == 2){
            importExeclIntellectual(file,termId,type);
        }else if(type == 1){
            importExeclMoral(file,termId,type);
        }

    }

    /**
     *上传文件
     * @param file
     * @param busiId
     * @param type
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int save(MultipartFile file, Long busiId, Integer type) throws Exception {
        //根据系统类型回去上传路径
        String uploadPath = SystemUtils.IS_OS_LINUX ? SysConstants.LINUX_PATH : SysConstants.WINDOWS_PATH;
        // 上传的文件采用日期文件夹进行分隔
        String uploadDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String dirPath = uploadPath + File.separator + uploadDate;
        String name = file.getOriginalFilename();
        String filePath = dirPath + File.separator +name;
        FileUtil.uploadFile(file, filePath);
        //组装附件信息
        SysFile sysFile = new SysFile();
        sysFile.setLastUpdateBy(SecurityUtils.getUsername());
        sysFile.setLastUpdateTime(new Date());
        sysFile.setCreateBy(SecurityUtils.getUsername());
        sysFile.setCreateTime(new Date());
        sysFile.setBusiId(busiId);
        sysFile.setType(type);
        sysFile.setPath(filePath);
        sysFile.setName(name);
        return sysFileMapper.add(sysFile);
    }

    @Override
    public List<SysFile> findList(Long busiId, Integer type) {
        return sysFileMapper.findList(busiId,type);
    }

    @Override
    public void download(String path, String name, HttpServletRequest request, HttpServletResponse response) throws IOException {
            FileUtil.download(path,name,request,response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delete(SysFile records) {
        FileUtil.deleteFile(records.getPath());
        return sysFileMapper.delete(records.getId());
    }

    @Override
    public String uploadImg(MultipartFile file) throws Exception {
        //获取文件名称
        String fileName = file.getOriginalFilename();
        //获取文件名后缀
        String suffix = fileName.substring(file.getOriginalFilename().lastIndexOf("."));
        if(!FileUtil.isImg(suffix)){
            throw new CscaException("文件类型错误");
        }
        //根据系统类型回去上传路径
        String uploadImgPath = (SystemUtils.IS_OS_LINUX ? SysConstants.LINUX_PATH : SysConstants.WINDOWS_PATH) +File.separator + "img";
        String fileNameNew = UUIDUtil.getUUid32()+suffix;
        String filePath = uploadImgPath + File.separator + fileNameNew;
        FileUtil.uploadFile(file, filePath);
        return httpImgUrl+fileNameNew;
    }

    /**
     * 通用Excel导入方法，将Excel数据导入到指定的Bean类
     * @param file Excel文件
     * @param clazz 目标Bean类
     * @param <T> Bean类型
     * @return 导入的数据列表
     * @throws Exception 导入异常
     */
    @Override
    public <T> List<T> importExcelForBean(MultipartFile file, Class<T> clazz) throws Exception {
        if (file == null || file.isEmpty()) {
            throw new CscaException("文件不能为空");
        }
        
        ImportParams importParams = new ImportParams();
        // 表头在第几行
        importParams.setTitleRows(0);
        // 距离表头中间有几行不要的数据
        importParams.setStartRows(0);
        // 第几个sheet页，下标从0开始计算
        importParams.setStartSheetIndex(0);
        // 验证数据
        importParams.setNeedVerfiy(true);

        try {
            // 导入Excel数据
            ExcelImportResult<T> result = ExcelImportUtil.importExcelMore(
                file.getInputStream(), clazz, importParams
            );
            
            // 校验是否有不合格的数据
            if (result.isVerfiyFail()) {
                List<T> errorList = result.getFailList();
                StringBuilder sb = new StringBuilder();
                sb.append("导入数据有错误: ");
                
                // 只显示前5个错误
                int showCount = Math.min(errorList.size(), 5);
                for (int i = 0; i < showCount; i++) {
                    sb.append("第").append(i + 1).append("条数据有误; ");
                }
                
                if (errorList.size() > 5) {
                    sb.append("等共").append(errorList.size()).append("条数据有误");
                }
                
                throw new CscaException(sb.toString());
            }
            
            // 返回合格的数据
            return result.getList();
        } catch (Exception e) {
            if (e instanceof CscaException) {
                throw e;
            }
            throw new CscaException("Excel导入异常: " + e.getMessage());
        }
    }

    /**
     * 体育成绩导入
     * @param file
     * @param termId
     * @param sheetNum
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void importExeclSports(MultipartFile file, Long termId, int sheetNum) throws Exception {
        ImportParams importParams = new ImportParams();
        // 表头在第几行
        importParams.setTitleRows(0);
        // 距离表头中间有几行不要的数据
        importParams.setStartRows(0);
        // 第几个sheet页，下标从0开始计算
        importParams.setStartSheetIndex(0);
        // 验证数据
        importParams.setNeedVerfiy(true);

        ExcelImportResult<BusScore> result = null;

        StringBuilder sb = new StringBuilder();

        try{
            result = ExcelImportUtil.importExcelMore(file.getInputStream(),
                    BusScore.class, importParams);
        }catch (Exception e){
            throw new CscaException("体育成绩导入异常");
        }
        // 校验是否合格
        if (result.isVerfiyFail()) {
            // 不合格的数据
            List<BusScore> errorList = result.getFailList();
            // 拼凑错误信息,自定义
            for (int i = 0; i < errorList.size(); i++) {
                EasyPoiUtil.getWrongInfo(sb, errorList, i, errorList.get(i), "studentNum", "用户信息为空");
            }
        }
        // 合格的数据
        List<BusScore> successList = result.getList();
        // 业务逻辑
        if (successList.size() > 0) {
            for (BusScore record:successList) {
                if(ObjectUtils.isNotEmpty(sysUserMapper.findByName(record.getStudentNum()))){
                    Map<String,Object> parmas = new HashMap<String,Object>();
                    parmas.put("termId",termId);
                    parmas.put("subjectType",2);
                    parmas.put("subjectName",record.getSubjectName().trim());
                    List<BusSubject> subjects = busSubjectMapper.findByParams(parmas);
                    if(subjects != null){
                        record.setSubjectId(subjects.get(0).getId());
                        record.setTermId(termId);
                        busScoreService.deleteByEntity(record);
                        busScoreService.save(record);
                    }

                }

            }
        }

    }

    /**
     * 拓展成绩导入
     * @param file
     * @param termId
     * @param sheetNum
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void importExeclExpand(MultipartFile file, Long termId, int sheetNum) throws Exception {
        ImportParams importParams = new ImportParams();
        // 表头在第几行
        importParams.setTitleRows(0);
        // 距离表头中间有几行不要的数据
        importParams.setStartRows(0);
        // 第几个sheet页，下标从0开始计算
        importParams.setStartSheetIndex(0);
        // 验证数据
        importParams.setNeedVerfiy(true);

        ExcelImportResult<BusExpand> result = null;

        StringBuilder sb = new StringBuilder();

        try{
            result = ExcelImportUtil.importExcelMore(file.getInputStream(),
                    BusExpand.class, importParams);
        }catch (Exception e){
            throw new CscaException("拓展成绩导入异常");
        }
        // 校验是否合格
        if (result.isVerfiyFail()) {
            // 不合格的数据
            List<BusExpand> errorList = result.getFailList();
            // 拼凑错误信息,自定义
            for (int i = 0; i < errorList.size(); i++) {
                EasyPoiUtil.getWrongInfo(sb, errorList, i, errorList.get(i), "studentNum", "用户信息为空");
            }
        }
        // 合格的数据
        List<BusExpand> successList = result.getList();
        // 业务逻辑
        if (successList.size() > 0) {
            for (BusExpand record:successList) {
                if(ObjectUtils.isNotEmpty(sysUserMapper.findByName(record.getStudentNum()))){
                    record.setTermId(termId);
                    busExpandService.deleteByEntity(record);
                    busExpandService.save(record);
                }

            }
        }

    }

    /**
     * 智育成绩导入
     * @param file
     * @param termId
     * @param sheetNum
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void importExeclIntellectual(MultipartFile file, Long termId, int sheetNum) throws Exception {
        ImportParams importParams = new ImportParams();
        // 表头在第几行
        importParams.setTitleRows(0);
        // 距离表头中间有几行不要的数据
        importParams.setStartRows(0);
        // 第几个sheet页，下标从0开始计算
        importParams.setStartSheetIndex(0);
        // 验证数据
        importParams.setNeedVerfiy(true);

        ExcelImportResult<BusScore> result = null;

        StringBuilder sb = new StringBuilder();

        try{
            result = ExcelImportUtil.importExcelMore(file.getInputStream(),
                    BusScore.class, importParams);
        }catch (Exception e){
            throw new CscaException("体育成绩导入异常");
        }
        // 校验是否合格
        if (result.isVerfiyFail()) {
            // 不合格的数据
            List<BusScore> errorList = result.getFailList();
            // 拼凑错误信息,自定义
            for (int i = 0; i < errorList.size(); i++) {
                EasyPoiUtil.getWrongInfo(sb, errorList, i, errorList.get(i), "studentNum", "用户信息为空");
            }
        }
        // 合格的数据
        List<BusScore> successList = result.getList();
        // 业务逻辑
        if (successList.size() > 0) {
            for (BusScore record:successList) {
                if(ObjectUtils.isNotEmpty(sysUserMapper.findByName(record.getStudentNum()))){
                    Map<String,Object> parmas = new HashMap<String,Object>();
                    parmas.put("termId",termId);
                    parmas.put("subjectType",1);
                    parmas.put("subjectName",record.getSubjectName().trim());
                    List<BusSubject> subjects = busSubjectMapper.findByParams(parmas);
                    if(subjects != null){
                        record.setSubjectId(subjects.get(0).getId());
                        record.setTermId(termId);
                        busScoreService.deleteByEntity(record);
                        busScoreService.save(record);
                    }

                }

            }
        }

    }

    /**
     * 德育成绩导入
     * @param file
     * @param termId
     * @param sheetNum
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void importExeclMoral(MultipartFile file, Long termId, int sheetNum) throws Exception {
        ImportParams importParams = new ImportParams();
        // 表头在第几行
        importParams.setTitleRows(0);
        // 距离表头中间有几行不要的数据
        importParams.setStartRows(0);
        // 第几个sheet页，下标从0开始计算
        importParams.setStartSheetIndex(0);
        // 验证数据
        importParams.setNeedVerfiy(true);

        ExcelImportResult<BusMoral> result = null;

        StringBuilder sb = new StringBuilder();

        try{
            result = ExcelImportUtil.importExcelMore(file.getInputStream(),
                    BusMoral.class, importParams);
        }catch (Exception e){
            throw new CscaException("拓展成绩导入异常");
        }
        // 校验是否合格
        if (result.isVerfiyFail()) {
            // 不合格的数据
            List<BusMoral> errorList = result.getFailList();
            // 拼凑错误信息,自定义
            for (int i = 0; i < errorList.size(); i++) {
                EasyPoiUtil.getWrongInfo(sb, errorList, i, errorList.get(i), "studentNum", "用户信息为空");
            }
        }
        // 合格的数据
        List<BusMoral> successList = result.getList();
        // 业务逻辑
        if (successList.size() > 0) {
            for (BusMoral record:successList) {
                if(ObjectUtils.isNotEmpty(sysUserMapper.findByName(record.getStudentNum()))){
                    record.setTermId(termId);
                    busMoralService.deleteByEntity(record);
                    busMoralService.save(record);
                }

            }
        }

    }


}
